<template>
  <div class="notification-center">
    <!-- 通知按钮 -->
    <div class="notification-trigger" @click="togglePanel">
      <button
        class="notification-button"
        :class="{ 'has-unread': hasUnreadNotifications }"
      >
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>
          <path d="M13.73 21a2 2 0 0 1-3.46 0"/>
        </svg>
        
        <!-- 未读数量徽章 -->
        <span
          v-if="unreadCount > 0"
          class="notification-badge"
        >
          {{ unreadCount > 99 ? '99+' : unreadCount }}
        </span>
      </button>
    </div>
    
    <!-- 通知面板 -->
    <Transition name="notification-panel">
      <div
        v-if="showPanel"
        class="notification-panel"
        @click.stop
      >
        <!-- 面板头部 -->
        <div class="panel-header">
          <h3 class="panel-title">通知中心</h3>
          <div class="panel-actions">
            <button
              v-if="hasUnreadNotifications"
              @click="markAllAsRead"
              class="action-button"
              :disabled="markingAllAsRead"
            >
              全部已读
            </button>
            <button
              @click="clearAllNotifications"
              class="action-button text-red-600"
              :disabled="clearingAll"
            >
              清空
            </button>
            <button
              @click="closePanel"
              class="close-button"
            >
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <line x1="18" y1="6" x2="6" y2="18"/>
                <line x1="6" y1="6" x2="18" y2="18"/>
              </svg>
            </button>
          </div>
        </div>
        
        <!-- 过滤器 -->
        <div class="panel-filters">
          <button
            v-for="filter in filters"
            :key="filter.value"
            @click="currentFilter = filter.value"
            class="filter-button"
            :class="{ 'active': currentFilter === filter.value }"
          >
            {{ filter.label }}
            <span v-if="filter.count > 0" class="filter-count">
              {{ filter.count }}
            </span>
          </button>
        </div>
        
        <!-- 通知列表 -->
        <div class="notification-list">
          <div
            v-if="loading"
            class="loading-state"
          >
            <div class="loading-spinner"></div>
            <span>加载中...</span>
          </div>
          
          <div
            v-else-if="filteredNotifications.length === 0"
            class="empty-state"
          >
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
              <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>
              <path d="M13.73 21a2 2 0 0 1-3.46 0"/>
            </svg>
            <p>暂无通知</p>
          </div>
          
          <div
            v-else
            class="notifications-container"
          >
            <div
              v-for="notification in filteredNotifications"
              :key="notification.id"
              class="notification-item"
              :class="{
                'unread': !notification.is_read,
                'clickable': notification.action_url
              }"
              @click="handleNotificationClick(notification)"
            >
              <!-- 通知图标 -->
              <div class="notification-icon" :class="getNotificationIconClass(notification.type)">
                <component :is="getNotificationIcon(notification.type)" />
              </div>
              
              <!-- 通知内容 -->
              <div class="notification-content">
                <div class="notification-header">
                  <h4 class="notification-title">{{ notification.title }}</h4>
                  <span class="notification-time">{{ formatTime(notification.created_at) }}</span>
                </div>
                
                <p class="notification-message">{{ notification.message }}</p>
                
                <!-- 通知操作 -->
                <div v-if="notification.action_url || notification.action_text" class="notification-actions">
                  <button
                    v-if="notification.action_text"
                    @click.stop="handleNotificationAction(notification)"
                    class="notification-action-button"
                  >
                    {{ notification.action_text }}
                  </button>
                </div>
              </div>
              
              <!-- 未读指示器 -->
              <div v-if="!notification.is_read" class="unread-indicator"></div>
              
              <!-- 删除按钮 -->
              <button
                @click.stop="deleteNotification(notification.id)"
                class="delete-button"
                :disabled="deletingIds.includes(notification.id)"
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <line x1="18" y1="6" x2="6" y2="18"/>
                  <line x1="6" y1="6" x2="18" y2="18"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
        
        <!-- 加载更多 -->
        <div
          v-if="hasMore && !loading"
          class="load-more"
        >
          <button
            @click="loadMore"
            class="load-more-button"
            :disabled="loadingMore"
          >
            {{ loadingMore ? '加载中...' : '加载更多' }}
          </button>
        </div>
      </div>
    </Transition>
    
    <!-- 遮罩层 -->
    <Transition name="notification-overlay">
      <div
        v-if="showPanel"
        class="notification-overlay"
        @click="closePanel"
      ></div>
    </Transition>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useNotificationStore } from '@/stores/notification'
import { formatDistanceToNow } from 'date-fns'
import { zhCN } from 'date-fns/locale'

interface Notification {
  id: string
  type: 'info' | 'success' | 'warning' | 'error' | 'task'
  title: string
  message: string
  is_read: boolean
  created_at: string
  action_url?: string
  action_text?: string
  task_id?: string
}

// Store
const notificationStore = useNotificationStore()

// 响应式数据
const showPanel = ref(false)
const currentFilter = ref('all')
const loading = ref(false)
const loadingMore = ref(false)
const markingAllAsRead = ref(false)
const clearingAll = ref(false)
const deletingIds = ref<string[]>([])

// 计算属性
const notifications = computed(() => notificationStore.notifications)
const unreadCount = computed(() => notificationStore.unreadCount)
const hasUnreadNotifications = computed(() => unreadCount.value > 0)
const hasMore = computed(() => notificationStore.hasMore)

const filters = computed(() => [
  { label: '全部', value: 'all', count: notifications.value.length },
  { label: '未读', value: 'unread', count: unreadCount.value },
  { label: '任务', value: 'task', count: notifications.value.filter(n => n.type === 'task').length },
  { label: '系统', value: 'system', count: notifications.value.filter(n => n.type !== 'task').length }
])

const filteredNotifications = computed(() => {
  let filtered = notifications.value
  
  switch (currentFilter.value) {
    case 'unread':
      filtered = filtered.filter(n => !n.is_read)
      break
    case 'task':
      filtered = filtered.filter(n => n.type === 'task')
      break
    case 'system':
      filtered = filtered.filter(n => n.type !== 'task')
      break
  }
  
  return filtered
})

// 方法
const togglePanel = () => {
  showPanel.value = !showPanel.value
  if (showPanel.value && notifications.value.length === 0) {
    loadNotifications()
  }
}

const closePanel = () => {
  showPanel.value = false
}

const loadNotifications = async () => {
  loading.value = true
  try {
    await notificationStore.fetchNotifications()
  } catch (error) {
    console.error('Failed to load notifications:', error)
  } finally {
    loading.value = false
  }
}

const loadMore = async () => {
  loadingMore.value = true
  try {
    await notificationStore.fetchNotifications(true)
  } catch (error) {
    console.error('Failed to load more notifications:', error)
  } finally {
    loadingMore.value = false
  }
}

const markAllAsRead = async () => {
  markingAllAsRead.value = true
  try {
    await notificationStore.markAllAsRead()
  } catch (error) {
    console.error('Failed to mark all as read:', error)
  } finally {
    markingAllAsRead.value = false
  }
}

const clearAllNotifications = async () => {
  if (!confirm('确定要清空所有通知吗？')) return
  
  clearingAll.value = true
  try {
    await notificationStore.clearAll()
  } catch (error) {
    console.error('Failed to clear notifications:', error)
  } finally {
    clearingAll.value = false
  }
}

const deleteNotification = async (id: string) => {
  deletingIds.value.push(id)
  try {
    await notificationStore.deleteNotification(id)
  } catch (error) {
    console.error('Failed to delete notification:', error)
  } finally {
    deletingIds.value = deletingIds.value.filter(deletingId => deletingId !== id)
  }
}

const handleNotificationClick = async (notification: Notification) => {
  // 标记为已读
  if (!notification.is_read) {
    await notificationStore.markAsRead(notification.id)
  }
  
  // 处理点击动作
  if (notification.action_url) {
    if (notification.action_url.startsWith('http')) {
      window.open(notification.action_url, '_blank')
    } else {
      // 内部路由跳转
      // router.push(notification.action_url)
      closePanel()
    }
  }
}

const handleNotificationAction = async (notification: Notification) => {
  await handleNotificationClick(notification)
}

const getNotificationIcon = (type: string) => {
  const icons = {
    info: 'svg',
    success: 'svg',
    warning: 'svg',
    error: 'svg',
    task: 'svg'
  }
  return icons[type as keyof typeof icons] || 'svg'
}

const getNotificationIconClass = (type: string) => {
  const classes = {
    info: 'text-blue-500 bg-blue-50',
    success: 'text-green-500 bg-green-50',
    warning: 'text-yellow-500 bg-yellow-50',
    error: 'text-red-500 bg-red-50',
    task: 'text-purple-500 bg-purple-50'
  }
  return classes[type as keyof typeof classes] || 'text-gray-500 bg-gray-50'
}

const formatTime = (dateString: string) => {
  try {
    const date = new Date(dateString)
    return formatDistanceToNow(date, { 
      addSuffix: true, 
      locale: zhCN 
    })
  } catch (error) {
    return dateString
  }
}

// 点击外部关闭面板
const handleClickOutside = (event: Event) => {
  const target = event.target as Element
  if (!target.closest('.notification-center')) {
    closePanel()
  }
}

// 生命周期
onMounted(() => {
  document.addEventListener('click', handleClickOutside)
  // 初始化通知数据
  notificationStore.fetchNotifications()
})

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
})

// 监听WebSocket通知
watch(() => notificationStore.newNotification, (newNotification) => {
  if (newNotification) {
    // 可以在这里添加通知提示音或其他效果
    console.log('New notification received:', newNotification)
  }
})
</script>

<style scoped>
.notification-center {
  position: relative;
}

.notification-trigger {
  position: relative;
}

.notification-button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: none;
  background: transparent;
  border-radius: 8px;
  color: #6b7280;
  cursor: pointer;
  transition: all 0.2s ease;
}

.notification-button:hover {
  background: #f3f4f6;
  color: #374151;
}

.notification-button.has-unread {
  color: #3b82f6;
}

.notification-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  background: #ef4444;
  color: white;
  font-size: 10px;
  font-weight: 600;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.notification-panel {
  position: absolute;
  top: 100%;
  right: 0;
  width: 380px;
  max-height: 600px;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  margin-top: 8px;
}

.notification-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
}

/* 面板头部 */
.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #e5e7eb;
}

.panel-title {
  font-size: 16px;
  font-weight: 600;
  color: #111827;
  margin: 0;
}

.panel-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.action-button {
  padding: 4px 8px;
  font-size: 12px;
  border: none;
  background: transparent;
  color: #6b7280;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.action-button:hover {
  background: #f3f4f6;
  color: #374151;
}

.action-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.close-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: #6b7280;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.close-button:hover {
  background: #f3f4f6;
  color: #374151;
}

/* 过滤器 */
.panel-filters {
  display: flex;
  padding: 12px 20px;
  gap: 8px;
  border-bottom: 1px solid #f3f4f6;
}

.filter-button {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  font-size: 12px;
  border: 1px solid #e5e7eb;
  background: white;
  color: #6b7280;
  cursor: pointer;
  border-radius: 16px;
  transition: all 0.2s ease;
}

.filter-button:hover {
  border-color: #d1d5db;
  color: #374151;
}

.filter-button.active {
  background: #3b82f6;
  border-color: #3b82f6;
  color: white;
}

.filter-count {
  background: rgba(0, 0, 0, 0.1);
  color: inherit;
  padding: 2px 6px;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 600;
  min-width: 16px;
  text-align: center;
}

.filter-button.active .filter-count {
  background: rgba(255, 255, 255, 0.2);
}

/* 通知列表 */
.notification-list {
  flex: 1;
  overflow-y: auto;
  max-height: 400px;
}

.loading-state,
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  color: #6b7280;
}

.loading-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid #e5e7eb;
  border-top: 2px solid #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 12px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.empty-state svg {
  margin-bottom: 12px;
  opacity: 0.5;
}

.notifications-container {
  padding: 8px 0;
}

.notification-item {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 20px;
  border-bottom: 1px solid #f3f4f6;
  transition: all 0.2s ease;
}

.notification-item:hover {
  background: #f9fafb;
}

.notification-item.unread {
  background: #f0f9ff;
}

.notification-item.clickable {
  cursor: pointer;
}

.notification-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.notification-content {
  flex: 1;
  min-width: 0;
}

.notification-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}

.notification-title {
  font-size: 14px;
  font-weight: 500;
  color: #111827;
  margin: 0;
  line-height: 1.4;
}

.notification-time {
  flex-shrink: 0;
  font-size: 11px;
  color: #9ca3af;
}

.notification-message {
  font-size: 13px;
  color: #6b7280;
  line-height: 1.4;
  margin: 0;
  word-break: break-word;
}

.notification-actions {
  margin-top: 8px;
}

.notification-action-button {
  padding: 4px 12px;
  font-size: 12px;
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.notification-action-button:hover {
  background: #2563eb;
}

.unread-indicator {
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 4px;
  background: #3b82f6;
  border-radius: 50%;
}

.delete-button {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: #9ca3af;
  cursor: pointer;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: all 0.2s ease;
}

.notification-item:hover .delete-button {
  opacity: 1;
}

.delete-button:hover {
  background: #fee2e2;
  color: #dc2626;
}

.delete-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 加载更多 */
.load-more {
  padding: 16px 20px;
  border-top: 1px solid #f3f4f6;
}

.load-more-button {
  width: 100%;
  padding: 8px 16px;
  font-size: 14px;
  background: transparent;
  color: #3b82f6;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.load-more-button:hover {
  background: #f0f9ff;
  border-color: #3b82f6;
}

.load-more-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 动画 */
.notification-panel-enter-active,
.notification-panel-leave-active {
  transition: all 0.3s ease;
}

.notification-panel-enter-from {
  opacity: 0;
  transform: translateY(-10px) scale(0.95);
}

.notification-panel-leave-to {
  opacity: 0;
  transform: translateY(-10px) scale(0.95);
}

.notification-overlay-enter-active,
.notification-overlay-leave-active {
  transition: opacity 0.3s ease;
}

.notification-overlay-enter-from,
.notification-overlay-leave-to {
  opacity: 0;
}

/* 响应式设计 */
@media (max-width: 640px) {
  .notification-panel {
    width: 320px;
    max-height: 500px;
  }
  
  .panel-header {
    padding: 12px 16px;
  }
  
  .panel-filters {
    padding: 8px 16px;
  }
  
  .notification-item {
    padding: 12px 16px;
  }
  
  .load-more {
    padding: 12px 16px;
  }
}
</style>